/* conartist.c */

/*
 * Licensed to the ConArtist Development Team (CADT).
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 * The CADT licenses this file to you under the Apache License, 
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <apr_strings.h>

#include "conartist.h"
#include "caLog.h"
#include "caGenerator.h"

#include "caPrivate.h"

apr_pool_t *globalPool = NULL;

apr_status_t caInit(apr_pool_t *parent)
{
    char *verString = NULL;
    apr_status_t rv;

    if (!globalPool) {
        rv = apr_pool_create(&globalPool, parent);
        if (rv != APR_SUCCESS)
            goto clean_exit;

        libConfig = apr_table_make(globalPool, 1);
        if (! libConfig) {
            rv = APR_ENOMEM;
            goto clean_exit;
        }
    }

    verString = apr_psprintf(globalPool, "%d.%02d.%02d (%s)", 
                             CA_VER_MAJOR,
                             CA_VER_MINOR,
                             CA_VER_RELEASE,
                             CA_VER_QUALITY);
    apr_table_set(libConfig, "Version", verString);

#define RUN_INIT(fn, str)    \
    rv = fn();               \
    if (rv != APR_SUCCESS) { \
        caLog(CA_LOG_ERROR, "#str# failed to initialise"); \
        goto clean_exit; \
    }

    
    /* Now run the various component init routines... 
     * The order is important here as some modules create pools which
     * will need to be cleaned up. The order of the clearing is last in,
     * first out, so anything all dependancies must be earlier in this 
     * list.*/
    RUN_INIT(logInit, "Logging");
    RUN_INIT(dsoInit, "Modules");
    RUN_INIT(pipeInit, "Pipes");
    RUN_INIT(storeInit, "Stores");
    RUN_INIT(genInit, "Generators");

    /* Default log level is CA_LOG_ERROR */
    apr_table_set(libConfig, "DEFAULT_LOG_LEVEL", "2");

    return APR_SUCCESS;
clean_exit:
    if (globalPool)
        apr_pool_destroy(globalPool);

    return rv;
}

apr_status_t caTerminate(void *data)
{
    /* TODO - shut down processes here! */

    apr_pool_destroy(globalPool);
    apr_terminate();
    return APR_SUCCESS;
}

const char *caGetVersion(void)
{
    return apr_table_get(libConfig, "Version");
}

apr_status_t caGetContent(struct caContent *req)
{
    struct caGenerator *g;
    apr_status_t rv;

    if (!req->uri) {
        caLog(CA_LOG_ERROR, "Received request for NULL uri!");
        return APR_EINVAL;
    }

    req->dataLen = 0;
    req->data = NULL;
    req->filename = NULL;

    rv = caGeneratorFind(&g, req->hostname, req->port, req->uri);
    if (rv != APR_SUCCESS || !g) {
        caLog(CA_LOG_WARN, "Unable to find a generator to process host '%s:%d'",
              req->hostname, req->port);
        return rv;
    }
    caLog(CA_LOG_INFO, "Processing URI '%s' using generator '%s'",
          req->uri, g->name);
    return caGeneratorProcessRequest(g, req);
}
